package com.lyf.core.log.aspect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.lyf.core.compant.Perm;
import com.lyf.core.pojo.User;
import com.lyf.core.service.LogService;

@Component
@Aspect
public class LogAspect {
 
	private Logger logger = Logger.getLogger(getClass());
	
	@Autowired
	LogService logService  ;
	 
	@Pointcut("@annotation(com.lyf.core.compant.Perm)")
	public void logAop(){
		
	}
	
	public LogAspect() {
		// TODO Auto-generated constructor stub
		System.out.println("LogAspect start #####################################");
	}
	
	@After("logAop()")
	public void after(JoinPoint joinPoint) {
		  
		handleLog(joinPoint, null);
		
	}
	
	
	@AfterThrowing(value="logAop()",throwing="e")  
	public void doAfter(JoinPoint joinPoint, Exception e) {  
		 
		handleLog(joinPoint, e);

	}
	

    private void handleLog(JoinPoint joinPoint,Exception e) {  
    	
     	
        try {  
        	Perm logger = getPerm(joinPoint);
       	 	if(logger == null){  
                return;  
            }  
            String model = logger.model();
            OptType opType = logger.optType();
            String name = logger.name();
            
            //获取方法参数
             
            Object[] args = joinPoint.getArgs();
           
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            
            String[] paramNames = methodSignature.getParameterNames();
            
            String content = null;
            if(logger.optType() == OptType.SAVE || logger.optType() == OptType.UPDATE || logger.optType() == OptType.QUERY){
            	Object obj = getHasEntityArg(args , paramNames);
                //如果没有不做处理
                if(obj != null){
                	content = getContent(obj);
                }
                 
            }else if(logger.optType() == OptType.REMOVE){
            	if(args.length != 1){
            		return;
            	}
 
            	content = "删除ID:" + (args != null && args.length > 0 ? args[0] : "") + "记录";
            }
      
			 
			User u = getUser() ; 
			InfoLog log = new InfoLog(u == null ? -1 : u.getId() , u == null ? "" : u.getUser_name() , model, name, content, opType, 
					e != null ? "失败" : "成功" );
			
			log.setException(e == null ? null : e.toString());
			 
			logService.insertLog(log);
        } catch (Exception exp) {  
            exp.printStackTrace();  
            logger.error("写日志失败" , e);
        }  
    }

	
	private Perm getPerm(JoinPoint joinPoint) {
		Signature signature = joinPoint.getSignature();  
        MethodSignature methodSignature = (MethodSignature) signature;  
        Method method = methodSignature.getMethod();  
        if (method == null) {  
        	return null;  
        }  
        //获得注解  
        Perm logger = method.getAnnotation(Perm.class);
        return logger;
	}
	
	  /**
     * 获取有@Entity 注解的参数
     * @param args
     * @return
     */
	private Object getHasEntityArg(Object[] args ,  String[] params) {
		
		Map<String, Object> map = new HashMap<String, Object>();
		
		for(int i = 0 ; i < args.length && i < params.length ; i++) {
			map.put(params[i], args[i]);
		}
		
		 
		return map;
	}
	
	private String getContent(Object obj)
			throws IllegalAccessException, InvocationTargetException {
		
		if(obj == null) return "" ;
		
		String content = JSON.toJSONString(obj);
		/*if(obj instanceof List){
			List<?> list =(List<?>)obj;
			if(list.isEmpty()){
				return "";
			}
			
			StringBuffer sb = new StringBuffer();
			int index = 0;
			for(Object v : list) {
				index++ ;
				String json = JSON.toJSONString(v);
				
				sb.append(index + " = " + json + ",");
				 
			}
			sb.deleteCharAt(sb.length() - 1);
			 
		    content = sb.toString();
		     
		}else{
			 
			content = JSON.toJSONString(obj);
			 
		}*/
		return content;
	}

	
	public User getUser() {
		
		Object user = SecurityUtils.getSubject().getSession().getAttribute("user");
		if(user != null && user instanceof User) {
			
			return ((User) user);
			
		}
	 
		return null ;
	}
	 
}
